package com.lvhaosb.newpneumonia.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class ServiceAspect {

    @Pointcut("execution(* com.lvhaosb.newpneumonia..*.service.impl.*.*(..))")
    public void pointCut() {
    }

    /**
     * 前置通知
     *
     * 方法执行之前， 如果返回为真，那么后面的逻辑继续 如果返回为价，则方法不会被执行
     *
     * @param target 目标对象
     * @param proxy  代理对象
     * @param method 目标对象的每一个方法
     * @param args   执行该方法的参数
     * @return
     */
    @Before("pointCut()")
    public boolean before(JoinPoint jp) {
        System.out.println("before");
        return true;
    }

    /**
     * 环绕通知 方法在执行的时候 会得到方法执行的结果 方法如果真的被执行了，只能在环绕里面执行
     *
     * @param target
     * @param proxy
     * @param method
     * @param args
     * @return
     */
    @Around("pointCut()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("around");
        Object result = pjp.proceed();
        return result;
    }

    /**
     * 后置通知 方法执行之后，在执行这个节点的时候，方法已经到返回值了， 所以在参数中能够接受方法的结果
     *
     * @param result 方法执行的结果
     * @param target
     * @param proxy
     * @param method
     * @param args
     */
    @AfterReturning(pointcut = "pointCut()", returning = "result")
    public void afterReturning(JoinPoint jp, Object result) {
        System.out.println("afterReturning");
    }

    /**
     * 异常通知 当方法抛出异常之后
     *
     * @param e      方法所抛出的异常
     * @param target
     * @param proxy
     * @param method
     * @param args
     */
    @AfterThrowing(pointcut = "pointCut()", throwing = "e")
    public void afterThrowing(JoinPoint jp, Exception e) {
        System.out.println("afterThrowing");
    }

    /**
     * 最终通知 最终 方法不论是否正常结束都会被调用
     *
     * @param target
     * @param proxy
     * @param method
     * @param args
     */
    @After("pointCut()")
    public void after(JoinPoint jp) {
        System.out.println("after");
    }
}
